using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using EnvDTE;
using CodeNamespace=System.CodeDom.CodeNamespace;

namespace NUnitGenAddIn.Core
{
    /// <summary>
    /// Code Dom Helper
    /// </summary>
	public class CodeDomHelper
	{
        /// <summary>
        /// Creates the variable declaration statement.
        /// </summary>
        /// <param name="variableType">Type of the variable.</param>
        /// <param name="variableName">Name of the variable.</param>
        /// <returns></returns>
		public CodeVariableDeclarationStatement CreateVariableDeclarationStatement(CodeTypeRef variableType,
		                                                                           string variableName)
		{
			CodeTypeReference typeRef;
			if (variableType.TypeKind == vsCMTypeRef.vsCMTypeRefArray)
				typeRef = CreateArrayTypeReference(variableType);
			else
				typeRef = new CodeTypeReference(variableType.AsFullName.Length > 0 ? variableType.AsFullName : variableType.AsString);

			return new CodeVariableDeclarationStatement(typeRef, variableName, new CodePrimitiveExpression(null));
		}

        /// <summary>
        /// Creates the array type reference.
        /// </summary>
        /// <param name="variableType">Type of the variable.</param>
        /// <returns></returns>
		protected virtual CodeTypeReference CreateArrayTypeReference(CodeTypeRef variableType)
		{
			return new CodeTypeReference(variableType.ElementType.AsFullName, variableType.Rank);
		}

        /// <summary>
        /// Parses the specified code stream.
        /// </summary>
        /// <param name="codeStream">The code stream.</param>
        /// <returns></returns>
		public virtual CodeCompileUnit Parse(TextReader codeStream)
		{
			throw new NotImplementedException(
				"Due to different implementation of CSharpCodeProvider.CreateParser in EnvDTE and EnvDTE2, you must implement this function.");
		}

        /// <summary>
        /// Generates the code from compile unit.
        /// </summary>
        /// <param name="compileUnit">The compile unit.</param>
        /// <param name="writer">The writer.</param>
        /// <param name="options">The options.</param>
		public virtual void GenerateCodeFromCompileUnit(CodeCompileUnit compileUnit, TextWriter writer, CodeGeneratorOptions options)
		{
			throw new NotImplementedException(
				"Due to different implementation of CSharpCodeProvider.GenerateCodeFromCompileUnit in versions of CodeDom, you must implement this function.");
		}

        /// <summary>
        /// Generates the code from statement.
        /// </summary>
        /// <param name="statement">The statement.</param>
        /// <param name="writer">The writer.</param>
        /// <param name="options">The options.</param>
		public virtual void GenerateCodeFromStatement(CodeStatement statement, TextWriter writer, CodeGeneratorOptions options)
		{
			throw new NotImplementedException(
				"Due to different implementation of CSharpCodeProvider.GenerateCodeFromCompileUnit in versions of CodeDom, you must implement this function.");
		}

        /// <summary>
        /// Generates the code from <c>Namespace</c>.
        /// </summary>
        /// <param name="codeNamespace">The code <c>Namespace</c>.</param>
        /// <param name="writer">The writer.</param>
        /// <param name="options">The options.</param>
		public virtual void GenerateCodeFromNameSpace(CodeNamespace codeNamespace, TextWriter writer, CodeGeneratorOptions options)
		{
			throw new NotImplementedException(
				"Due to different implementation of CSharpCodeProvider.GenerateCodeFromNameSpace in versions of CodeDom, you must implement this function.");
		}
	}
}